<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/11/29
 * Time: 18:28
 */

namespace app\api\service;

use app\lib\Exception\ForbiddenException;
use app\lib\Exception\TokenException;
use think\Cache;
use think\Exception;
use think\Request;

class Token
{
    public static function onlyScope($status)
    {
        $scope = self::getTokenVar('scope');
        if ($scope) {
            if ($scope == $status) {
                return true;
            } else {
                throw new ForbiddenException();
            }
        } else {
            throw new TokenException();
        }
    }

    public static function moreScope($status)
    {
        $scope = self::getTokenVar('scope');
        if ($scope) {
            if ($scope >= $status) {
                return true;
            } else {
                throw new ForbiddenException();
            }
        } else {
            throw new TokenException();
        }
    }

    /*
     * @status 权限
     * @only  true只有这一级有的权限  false这级和更高级的都有权限
     * */
    public static function needScope($status, $only = false)
    {
        if (!$only) {
            return self::moreScope($status);
        } else {
            return self::onlyScope($status);
        }
    }

    // public static function needBaseScope(){
    //     $scope = self::getTokenVar('scope');
    //     if($scope){
    //         if($scope >= ScopeEnum::User){
    //             return true;
    //         } else{
    //             throw new ForbiddenException();
    //         }
    //     } else{
    //         throw new TokenException();
    //     }
    // }
    //
    // public static function onlyUserScope(){
    //     $scope = self::getTokenVar('scope');
    //     if($scope){
    //         if($scope == ScopeEnum::User){
    //             return true;
    //         }else{
    //             throw new ForbiddenException([]);
    //         }
    //     }
    //     throw new TokenException();
    // }
    //
    // public static function needSuperScope(){
    //     $scope = self::getTokenVar('scope');
    //     if($scope){
    //         if($scope == ScopeEnum::Super){
    //             return true;
    //         }else{
    //             throw new ForbiddenException([]);
    //         }
    //     }
    //     throw new TokenException();
    // }



    public static function saveCache($cache)
    {
        $key = self::generateToken();
        // 数组转换为json
        $value = json_encode($cache);
        $expire= config('setting.token_expire_in');
        $result = cache($key,$value,$expire);
        if(!$result){
            // 缓存出错
            throw new TokenException([
                'info'=>'服务器缓存异常',
                'errorCode'=>10005
            ]);
        }
        return $key;
    }

    public static function verifyToken($token){
        $exist = Cache::get($token);
        if($exist){
            return true;
        }
        else{
            return false;
        }
    }

    public static function generateToken()
    {
        $randChar = getRandChar(32);
        // 时间戳
        $timestamp = $_SERVER['REQUEST_TIME_FLOAT'];
        $tokenSalt = config('secure.token_salt');
        // md5 生成token
        return md5($randChar . $timestamp . $tokenSalt);
    }

    public static function getTokenVar($key)
    {
        // 用户在header传递token
        $token = Request::instance()->header("token");
        $vars = Cache::get($token);
        // 没有获取到缓存
        if (!$vars) {
            throw new TokenException();
        }

        if (!is_array($vars)) {
            // 转换成array
            $vars = json_decode($vars, true);
        }

        if (key_exists($key, $vars)) {
            return $vars[$key];
        } else {
            throw new Exception('尝试获取的Token变量并不存在');
        }
    }

    public static function getCurrentUid()
    {
        return self::getTokenVar('uid');
    }

    public static function isValidateOperate($checkedID){
        if(!$checkedID){
            throw new Exception('需要传入被检查的uid');
        }

        if($checkedID == self::getCurrentUid()){
            return true;
        }
        return false;
    }
}